我們前面花了四篇,穿插了 S3 Bucket 如何收取資料。 但是要串預簽上傳網址的時候,會有點麻煩。 所以前一回用 EC2 來架 NginX;這東西要自己維護,還要 24 小時常駐開啟,如果你沒有使用 EC2 的習慣,或者不熟悉建立伺服器,或是你事情很多工作複雜,沒有時間來管理了,那就非常推薦你走 API Gateway + Lambda 的組合,管理會比較輕鬆!!
API Gateway 顧名思義,就是全託管的 API Server。 而 Lambda Function 就是你可以寫一段程式碼,運行在無伺服器環境中、由 AWS 官方管理的環境中。
lambda_handler(event, context)
import json
import boto3
import os
import urllib.parse
s3 = boto3.client("s3")
BUCKET_NAME = os.environ.get("BUCKET_NAME", "exsky-backup-media")
def lambda_handler(event, context):
# 解析前端傳來的檔案名稱
params = json.loads(event['body'])
filename = params.get("filename")
if not filename:
return {
"statusCode": 400,
"body": json.dumps({"error": "Missing filename"})
}
key = urllib.parse.quote(filename)
# 產生預簽名 URL(有效 10 分鐘)
presigned_url = s3.generate_presigned_url(
'put_object',
Params={'Bucket': BUCKET_NAME, 'Key': key},
ExpiresIn=600 # 10 分鐘 = 600 秒
)
return {
"statusCode": 200,
"body": json.dumps({"url": presigned_url})
}
BUCKET_NAME = os.environ.get("BUCKET_NAME", "exsky-backup-media")
這句是去抓環境變數 BUCKET_NAME 的值,如果抓不到,那回傳預設值 "exsky-backup-media"/generate-url
路由,綁定 POST 方法[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["PUT"],
"AllowedOrigins": ["*"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::exsky-backup-media/*"
}
const filename = "hello.jpg";
const response = await fetch("/generate-url", {
method: "POST",
body: JSON.stringify({ filename }),
});
const { url } = await response.json();
await fetch(url, {
method: "PUT",
body: file, // File object from <input type="file">
});